package com.yundingai.controller;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yundingai.service.impl.RedisAiCacheServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;


import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Author yangming
 * @Date 2025/7/16 15:10
 * @Description ai请求响应接口
 **/
@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/deepseek")
@Slf4j
public class AiController {
    private ChatClient chatClient;
    @Autowired
    private RedisAiCacheServiceImpl redisAiCacheServiceImpl;

    public AiController(ChatClient.Builder builder){
        this.chatClient=builder.defaultSystem("你好").build();
    }



    /**
     * @Author yangming
     * @Date 2025/7/16 16:12
     * @Description ai非流式接口
     **/
    @GetMapping("/ai/chat")
    public String chatApi(@RequestParam("message") String message){

        System.out.println(message);
        return chatClient.prompt()
                .user(message)
                .call()
                .content();
    }

    /**
     * @Author yangming
     * @Date 2025/7/18 17:30
     * @Description ai流式接口
     **/
    @GetMapping(value = "/stream/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> streamChats1(@RequestParam("message") String message, @RequestParam("userid") String userid) throws JsonProcessingException {

        AtomicReference<String> fullResponse = new AtomicReference<>("");
        ObjectMapper mapper = new ObjectMapper();
        //解析JSON格式
        List<RedisAiCacheServiceImpl.ChatMessage> userMessages = new ArrayList<>();
        // 解析消息
        userMessages = mapper.readValue(message, mapper.getTypeFactory().constructCollectionType(List.class, RedisAiCacheServiceImpl.ChatMessage.class));
        String pureUserMessage = userMessages.get(0).getContent();
        // 获取历史对话
        List<RedisAiCacheServiceImpl.ChatMessage> history = redisAiCacheServiceImpl.getChatHistory("chat:" + userid);
        // 标识对话历史
        StringBuilder promptBuilder = new StringBuilder();
        promptBuilder.append("请结合以下历史对话，回复用户的当前问题：\n");
        for (RedisAiCacheServiceImpl.ChatMessage msg : history) {
            String roleDesc = "user".equals(msg.getRole()) ? "用户" : "助手";
            promptBuilder.append(roleDesc).append("：").append(msg.getContent()).append("\n");
        }
        promptBuilder.append("用户当前的问题(回答去掉语句不通的*，#，-等符号只要必要标点)：").append(pureUserMessage).append("\n");
        String fullPrompt = promptBuilder.toString();
        //流式响应
        return chatClient.prompt()
                .user(fullPrompt)
                .stream()
                .content()
                .doOnNext(content -> {
                    fullResponse.updateAndGet(prev -> prev + content);
                })
                .doOnComplete(() -> {
                    try {
                        // 保存当前交互（用户消息+AI回复）
                        redisAiCacheServiceImpl.saveFullResponseToRedis(message, fullResponse.get(), userid);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                });
    }
    /**
     * 流式响应
     * @Author yamgming
     * @Date 2025/7/16 16:12
     * @Description ai流式接口
     */
    @GetMapping(value = "/stream/response",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> streamChat(@RequestParam("message") String message){
        Flux<ServerSentEvent<String>> responseStream = chatClient.prompt()
                .user(message)
                .stream()
                .content()
                .map(content -> ServerSentEvent.<String>builder().data(content).build());
        // 加后缀结束标识
        ServerSentEvent<String> doneMarker = ServerSentEvent.<String>builder()
                .data("[DONE]")
                .build();
        // 拼接
        return Flux.concat(responseStream, Flux.just(doneMarker));

    }

}
